/*******************************************************************************
 * Copyright © 2010-2020  陈恩点版权所有
 * Author: 陈恩点
 * First Create: 2012/8/21 11:49:53
 * Contact: 18115503914
 * Description: MyRapid快速开发框架
*********************************************************************************/
using MyRapid.Code;
using MyRapid.SysEntity;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Web;
namespace MyRapid.Server.Service
{
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class ApiService
    {
        DbHelper db = new DbHelper(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString, DbProviderType.SqlServer);
        // 要使用 HTTP GET，请添加 [WebGet] 特性。(默认 ResponseFormat 为 WebMessageFormat.Json)
        // 要创建返回 XML 的操作，
        //     请添加 [WebGet(ResponseFormat=WebMessageFormat.Xml)]，
        //     并在操作正文中包括以下行:
        //         WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        public ApiResult GetToken(string userName, string password)
        {
            try
            {
                HttpContext.Current.Response.Cookies.Add(new HttpCookie("token", string.Empty));
                string par = "@User_Name:{0}|@User_Password:{1}";
                par = string.Format(par, userName, password);
                string ReadSql = @"
                    DECLARE @User_Token NVARCHAR(50)
                    SET @User_Token = NEWID()
                    IF EXISTS (
                    SELECT 0
                    FROM  Sys_User
                    WHERE User_Name = @User_Name AND User_Password = @User_Password )
                    BEGIN
                    INSERT INTO Sys_Authentication (Authentication_Id ,Authentication_Name ,Authentication_Nick ,Authentication_User ,Authentication_Token ,Authentication_DateTime ,IsEnabled ,IsDelete ,Remark ,Create_User ,Create_Time ) 
                    SELECT NEWID() ,User_Name ,User_Nick ,User_Id ,@User_Token ,GETDATE() ,1 ,0 ,NULL ,User_Id ,GETDATE()
                    FROM  Sys_User
                    WHERE User_Name = @User_Name AND User_Password = @User_Password 
                    END
                    SELECT *,@User_Token User_Token FROM Sys_User Where User_Name = @User_Name AND User_Password = @User_Password";
                DataTable rdt = db.ExecuteDataTable(ReadSql, PreparParameters(par));
                if (rdt.Rows.Count > 0)
                {
                    Sys_User sys_User = EntityHelper.GetEntity<Sys_User>(rdt);
                    string token = sys_User.User_Token;
                    //token = EncryptHelper.DESEncrypt(sys_User.User_Id.ToString(), "myrapid.");
                    HttpContext.Current.Response.Cookies.Add(new HttpCookie("token", token));
                    sys_User.User_Password = token;
                    return new ApiResult(true, sys_User.ToJson(), "Succeed");
                }
                return new ApiResult(true, null, "用户名或密码不存在");
            }
            catch (Exception ex)
            {
                return new ApiResult(false, ex.ToJson(), "Exception");
            }
        }
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        public ApiResult GetJson(string s, string p, string token)
        {
            try
            {
                if (string.IsNullOrEmpty(s)) return null;
                Sys_WorkSet wkCmd = PreparWorkSet(s, token);
                if (wkCmd != null)
                {
                    string ReadSql = wkCmd.WorkSet_Select;
                    if (!string.IsNullOrEmpty(ReadSql))
                    {
                        string conn = db.ConnectionString;
                        if (!string.IsNullOrEmpty(wkCmd.WorkSet_Connection))
                        {
                            db.ConnectionString = wkCmd.WorkSet_Connection;
                        }
                        DataTable rdt = db.ExecuteDataTable(ReadSql, PreparParameters(p));
                        db.ConnectionString = conn;
                        return new ApiResult(true, rdt.ToJson(), "Succeed");
                    }
                }
            }
            catch (Exception ex)
            {
                return new ApiResult(false, ex.ToJson(), "Exception");
            }
            return new ApiResult(false, s, "IsNullOrEmpty");
        }
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        public ApiResult SetJson(string s, string p, string token)
        {
            try
            {
                if (string.IsNullOrEmpty(s)) return null;
                Sys_WorkSet wkCmd = PreparWorkSet(s, token);
                if (wkCmd != null)
                {
                    string ReadSql = wkCmd.WorkSet_Select;
                    if (!string.IsNullOrEmpty(ReadSql))
                    {
                        string conn = db.ConnectionString;
                        if (!string.IsNullOrEmpty(wkCmd.WorkSet_Connection))
                        {
                            db.ConnectionString = wkCmd.WorkSet_Connection;
                        }
                        int rit = db.ExecuteNonQuery(ReadSql, PreparParameters(p));
                        db.ConnectionString = conn;
                        return new ApiResult(true, rit.ToJson(), "Succeed");
                    }
                }
            }
            catch (Exception ex)
            {
                return new ApiResult(false, ex.ToJson(), "Exception");
            }
            return new ApiResult(false, s, "IsNullOrEmpty");
        }

        #region FileServer
        private string filePath = ConfigurationManager.AppSettings.Get("filePath");
        private string uploadPath = ConfigurationManager.AppSettings.Get("uploadPath");
        private List<Sys_File> SearchFile(string dirPath, List<Sys_File> sfs)
        {
            if (Directory.Exists(dirPath))
            {
                foreach (string fs in Directory.GetFiles(dirPath))
                {
                    Sys_File sf = new Sys_File();
                    sf.FileName = Path.GetFileName(fs);
                    //sf.FileByte = File.ReadAllBytes(fs);
                    sf.FileFullPath = fs;
                    sf.FilePath = fs.Replace(filePath, "").Trim('\\').Trim('/');
                    sf.FileDate = File.GetLastWriteTime(fs);
                    sf.FileType = Path.GetExtension(fs);
                    sfs.Add(sf);
                }
                foreach (string ds in Directory.GetDirectories(dirPath))
                {
                    SearchFile(ds, sfs);
                }
            }
            return sfs;
        }
        private List<Sys_File> ReadFile(string dirPath, List<Sys_File> sfs)
        {
            if (Directory.Exists(dirPath))
            {
                foreach (string fs in Directory.GetFiles(dirPath))
                {
                    Sys_File sf = new Sys_File();
                    sf.FileName = Path.GetFileName(fs);
                    sf.FileByte = File.ReadAllBytes(fs);
                    sf.FileFullPath = fs;
                    sf.FilePath = fs.Replace(dirPath, "").Trim('\\').Trim('/');
                    sf.FileDate = File.GetLastWriteTime(fs);
                    sf.FileType = Path.GetExtension(fs);
                    sfs.Add(sf);
                }
                foreach (string ds in Directory.GetDirectories(dirPath))
                {
                    ReadFile(ds, sfs);
                }
            }
            return sfs;
        }
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        public ApiResult GetAll()
        {
            try
            {
                List<Sys_File> sfs = new List<Sys_File>();
                sfs = SearchFile(filePath, sfs);
                return new ApiResult(true, sfs.ToJson(), "Succeed");
            }
            catch (Exception ex)
            {
                return new ApiResult(false, ex.ToJson(), "Exception"); ;
            }
        }
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        public ApiResult GetNew(DateTime ntime)
        {
            try
            {
                List<Sys_File> sfs = new List<Sys_File>();
                sfs = SearchFile(filePath, sfs).Where(f => f.FileDate > ntime).ToList();
                return new ApiResult(true, sfs.ToJson(), "Success");
            }
            catch (Exception ex)
            {
                return new ApiResult(false, ex.ToJson(), "Exception");
            }
        }
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        public ApiResult GetFile(string fileName)
        {
            try
            {
                List<Sys_File> sfs = new List<Sys_File>();
                sfs = ReadFile(filePath, sfs).Where(f => f.FileName == fileName).ToList();
                return new ApiResult(true, sfs.ToJson(), "Success");
            }
            catch (Exception ex)
            {
                return new ApiResult(false, ex.ToJson(), "Exception");
            }
        }
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        public ApiResult GetAllType(string ext)
        {
            try
            {
                List<Sys_File> sfs = new List<Sys_File>();
                sfs = SearchFile(filePath, sfs).Where(f => f.FileType == ext).ToList();
                return new ApiResult(true, sfs.ToJson(), "Success");
            }
            catch (Exception ex)
            {
                return new ApiResult(false, ex.ToJson(), "Exception");
            }
        }
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        public ApiResult GetNewType(DateTime ntime, string ext)
        {
            try
            {
                List<Sys_File> sfs = new List<Sys_File>();
                sfs = SearchFile(filePath, sfs).Where(f => f.FileDate > ntime).Where(f => f.FileType == ext).ToList();
                return new ApiResult(true, sfs.ToJson(), "Success");
            }
            catch (Exception ex)
            {
                return new ApiResult(false, ex.ToJson(), "Exception");
            }
        }
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        public ApiResult SetFiles(string files)
        {
            try
            {
                files = FilteHelper.Base64(files);
                string fjson = GZipHelper.Decompress(files);
                List<Sys_File> fs = fjson.ToObject<List<Sys_File>>();
                foreach (var item in fs)
                {
                    File.WriteAllBytes(string.Concat(uploadPath, @"\", item.FileId), item.FileByte);
                }
                return new ApiResult(true, null, "Success");
            }
            catch (Exception ex)
            {
                return new ApiResult(false, ex.ToJson(), "Exception");
            }
        }
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        public ApiResult SetFile(string file)
        {
            try
            {
                file = FilteHelper.Base64(file);
                string fjson = GZipHelper.Decompress(file);
                Sys_File fs = fjson.ToObject<Sys_File>();
                File.WriteAllBytes(string.Concat(uploadPath, @"\", fs.FileId), fs.FileByte);
                return new ApiResult(true, null, "Success");
            }
            catch (Exception ex)
            {
                return new ApiResult(false, ex.ToJson(), "Exception");
            }
        }
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        public ApiResult AppendFile(string file)
        {
            try
            {
                file = FilteHelper.Base64(file);
                string fjson = GZipHelper.Decompress(file);
                Sys_File fs = fjson.ToObject<Sys_File>();
                File.WriteAllBytes(string.Concat(uploadPath, @"\", fs.FileId), fs.FileByte);
                return new ApiResult(true, null, "Success");
            }
            catch (Exception ex)
            {
                return new ApiResult(false, ex.ToJson(), "Exception");
            }
        }
        #endregion

        private Sys_WorkSet PreparWorkSet(string worksetName, string token)
        {
            try
            {
                string sql = @"MyRapid_SqlCommand @WorkSet_Name ,@User_Id";
                string par = "@WorkSet_Name:{0}|@User_Id:{1}";
                par = string.Format(par, worksetName, token);
                DataTable sdt = db.ExecuteDataTable(sql, PreparParameters(par));
                List<Sys_WorkSet> wkCmd = EntityHelper.GetEntities<Sys_WorkSet>(sdt);
                if (wkCmd.Count > 0)
                    return wkCmd[0];
                return null;
            }
            catch //(Exception ex)
            {
                return null;
            }
        }
        //@2:2|@3:3
        private List<DbParameter> PreparParameters(string p)
        {
            List<DbParameter> sqlParameters = new List<DbParameter>();
            if (string.IsNullOrEmpty(p)) return sqlParameters;
            foreach (string value in p.Split('|'))
            {
                if (string.IsNullOrEmpty(value)) return sqlParameters;
                DbParameter sqlParameter = null;
                if (value.Contains(":"))
                {
                    string name = value.Split(':')[0];
                    string obj = value.Split(':')[1];
                    object vbj = obj;
                    if (string.IsNullOrEmpty(obj))
                    {
                        vbj = DBNull.Value;
                    }
                    sqlParameter = db.CreateDbParameter(name, DbType.String, vbj, null);
                    sqlParameters.Add(sqlParameter);
                }
            }
            return sqlParameters;
        }
        [DataContract]
        public class ApiResult
        {
            public ApiResult(bool succeed, string data, string message)
            {
                Succeed = succeed;
                Data = data;
                Message = message;
            }
            [DataMember]
            public bool Succeed { get; set; }
            [DataMember]
            public string Data { get; set; }
            [DataMember]
            public string Message { get; set; }
        }
    }
}